package when3meet.controller;

import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

import client.ServerAccess;

import when3meet.model.ClientInfo;
import when3meet.model.Edge;
import when3meet.view.Application;
import when3meet.view.MainFrame;
import xml.Message;

/**
 * Deal with GUI-based action, send addEdgeRequest. Handle add edge response
 * from server
 * 
 * @author Xi
 * 
 */
public class AddEdgeController implements ActionListener {

	public MainFrame mainFrame;
	ServerAccess access;

	public AddEdgeController(MainFrame mainFrame) {
		this.mainFrame = mainFrame;
	}

	/**
	 * Handle response from server
	 * 
	 * @param response
	 */
	public void process(Message response) {

		MainFrame.getInstance().getEventIdLabel().setVisible(false);

		Node update = response.contents.getFirstChild();
		ClientInfo ci = ClientInfo.getInstance();

		NamedNodeMap map = update.getAttributes();

		String id = map.getNamedItem("id").getNodeValue();
		int left = ((Integer.parseInt(map.getNamedItem("left").getNodeValue())) * MainFrame.getInstance()
				.getDecisionLineZone().getCurrentWidth()) + 19;
		int right = MainFrame.getInstance().getDecisionLineZone().getWidth();
		int height = Integer.parseInt(map.getNamedItem("height").getNodeValue());

		Edge e = new Edge(left, right, height);
		if (ci.getEventID().equals(id)) {

			Edge[] temp;
			if (ci.getEdges() == null) {
				temp = new Edge[1];
				temp[0] = e;
			} else {
				temp = new Edge[ci.getEdges().length + 1];
				for (int i = 0; i < temp.length - 1; i++)
					temp[i] = ci.getEdges()[i];

				temp[temp.length - 1] = e;
			}
			ci.setEdges(temp);

			// display the edges
			MainFrame.getInstance().getDecisionLineZone().addGlobalEdges(e);

			// for asynchronous mode, if edge from XML response equals
			// lastAddEdge in local model and current edge number is less than
			// maximum(numRounds), expand allowed edge number by 1.
			// for round-robin, doing nothing here, wait for turn response
			int currentAllowedEdge = MainFrame.getInstance().getDecisionLineZone().getCurrentAllowedEdge();

			if (ci.getLastAddEdge() != null) {

				System.out.println(ci.getLastAddEdge().left + " : " + ci.getLastAddEdge().height);
				if (ci.getLastAddEdge().left == left && ci.getLastAddEdge().height == height
						&& currentAllowedEdge < ci.getNumRounds()) {
					if (ci.getBehavior().equals("asynchronous")) {
						ci.setCurrentEdgeIndex(left);
						MainFrame.getInstance().getAddEdgeButton().setEnabled(true);
						MainFrame.getInstance().getDecisionLineZone().setCurrentAllowedEdge(currentAllowedEdge + 1);
						// hide event id label
						MainFrame.getInstance().getEventIdLabel().setVisible(false);
					}
				}
			}
		}

	}

	/**
	 * GUI-based controller, simply send XML request
	 */
	public void actionPerformed(ActionEvent e) {

		// Disable add edge button until get a response from server
		MainFrame.getInstance().getAddEdgeButton().setEnabled(false);

		sendRequest();

		// TODO sent edges' position cannot be change anymore!

	}

	public void sendRequest() {
		ClientInfo ci = ClientInfo.getInstance();

		mainFrame = MainFrame.getInstance();
		mainFrame.getDecisionLineZone().setWait();

		// store last added edge in local model, when get response from server
		// judge whether my edge been added successfully or not

		ci.setCurrentEdgeIndex(ci.getCurrentEdgeIndex() + 1);

		Rectangle newEdge = mainFrame.getDecisionLineZone().getEdge();
		Rectangle[] choices = mainFrame.getDecisionLineZone().getChoices();

		int left = 0;
		int right;
		int height = (int) newEdge.getY();

		for (int i = 0; i < choices.length; i++) {
			if (newEdge.getX() - 8 == choices[i].getX()) {
				left = i;
				break;
			}
		}
		right = left + 1;

		Edge e = new Edge(newEdge.x, newEdge.width, (int) newEdge.getY());
		ci.setLastAddEdge(e);

		String xmlString = Message.requestHeader() + "<addEdgeRequest " + "id = '" + ci.getEventID() + "' "
				+ "left = '" + left + "' " + "right = '" + right + "' " + "height = '" + height + "'/>" + "</request>";

		Message m = new Message(xmlString);
		access = Application.getInstance().getServerAccess();
		access.sendRequest(m);
	}

}
